﻿using System;
using System.Configuration;
using System.Threading.Tasks;
using EasyNetQ;
using EasyNetQ.FluentConfiguration;

namespace SP.DataExchange.ServiceBus
{
    public class ServiceBus : IServiceBus
    {
        private IBus _bus;

        public ServiceBus()
        {
            var connString = ConfigurationManager.AppSettings["bus"];
            _bus = RabbitHutch.CreateBus(connString);
        }

        public void Publish<T>(T message) where T : class
        {
            _bus.Publish(message);
        }

        public void Publish<T>(T message, string topic) where T : class
        {
            _bus.Publish(message, topic);
        }

        public async Task PublishAsync<T>(T message) where T : class
        {
            await _bus.PublishAsync(message);
        }

        public async Task PublishAsync<T>(T message, string topic) where T : class
        {
            await _bus.PublishAsync(message, topic);
        }

        public void Subscribe<T>(Action<T> onMessage, ushort? prefetchCount = null, string topic = null, bool? autoDelete = null, int? priority = null) where T : class
        {
            Subscribe("", onMessage, prefetchCount, topic, autoDelete, priority);
        }

        public void Subscribe<T>(string subscriptionId,Action<T> onMessage,ushort? prefetchCount = null,string topic = null,bool? autoDelete = null,int? priority = null) where T : class
        {
            Action<ISubscriptionConfiguration> config = x => {
                if (!string.IsNullOrEmpty(topic))
                    x.WithTopic(topic);

                if (autoDelete.HasValue)
                    x.WithAutoDelete(autoDelete.Value);

                if (priority.HasValue)
                    if (prefetchCount != null) x.WithPrefetchCount(prefetchCount.Value);

                if (autoDelete.HasValue)
                    x.WithAutoDelete(autoDelete.Value);
            };

            _bus.Subscribe(subscriptionId, onMessage, config);
        }

        public void Dispose()
        {
            if (_bus == null) return;
            _bus.Dispose();
            _bus = null;
        }
    }
}
